package gormc

import (
	stdlog "log"
	"os"
	"time"

	"go.uber.org/zap"
	glogger "gorm.io/gorm/logger"
)

type logOption struct {
	zapLogger     *zap.Logger
	logLevel      glogger.LogLevel
	slowThreshold time.Duration
	requestId     bool
}

type LogOptions func(opt *logOption)

func WithZapLogger(zapLogger *zap.Logger) LogOptions {
	return func(opt *logOption) {
		opt.zapLogger = zapLogger
	}
}

func WithLogLevel(level glogger.LogLevel) LogOptions {
	return func(opt *logOption) {
		opt.logLevel = level
	}
}

func WithSlowThreshold(slow time.Duration) LogOptions {
	return func(opt *logOption) {
		opt.slowThreshold = slow
	}
}

func WithRequestId(requestId bool) LogOptions {
	return func(opt *logOption) {
		opt.requestId = requestId
	}
}

func NewLogger(opts ...LogOptions) glogger.Interface {
	opt := &logOption{
		logLevel:      glogger.Warn,
		slowThreshold: 100 * time.Millisecond,
	}
	for _, o := range opts {
		o(opt)
	}
	if opt.zapLogger != nil {
		return GetZapLogger(opt.zapLogger, opt.logLevel, opt.slowThreshold, opt.requestId)
	}
	return GetDefaultLogger(opt.logLevel, opt.slowThreshold)
}

func GetDefaultLogger(level glogger.LogLevel, slow time.Duration) glogger.Interface {
	slowLogger := glogger.New(
		stdlog.New(os.Stdout, "\r\n", stdlog.LstdFlags),
		glogger.Config{
			SlowThreshold: slow,
			LogLevel:      level,
		},
	)
	return slowLogger
}

func GetZapLogger(log *zap.Logger, level glogger.LogLevel, slow time.Duration, requestId bool) glogger.Interface {
	slowLogger := NewZapLogger(log)
	slowLogger.LogMode(level)
	slowLogger.SlowThreshold = slow
	// if requestId {
	// 	slowLogger.Context = func(ctx context.Context) []zapcore.Field {
	// 		c, ok := ctx.(*gin.Context)
	// 		if !ok {
	// 			return nil
	// 		}
	// 		return []zapcore.Field{
	// 			zap.String("request_id", requestid.Get(c)),
	// 		}
	// 	}
	// }
	return slowLogger
}
